#include <stdio.h>
#include <stdlib.h>     //exit()
#include <string>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <wsim/websocket_common.h>
#include <wsim/websocket_server.h>
#include <map>
#include <jsoncpp/json/json.h>/* jsoncpp -ljsoncpp*/
#include "wsim.h"
#include "imDB.h"
#include <iostream>
#include "websocket_handler.h"
#include "execjson.h"
#include "wsim_server.h"
#include "myconfig.h"

using namespace std;

/***************************************
 * 服务器回复调用
 * 来：{"stype":"exec","exec":"调用名","param_1":"参数1"........}
 * 回:{"stype":"ret"，"exec":"调用名","return":"返回值“
 *      ,"arrayRet":[{"fd":6,"uuid":"518e1f56-0857-49a7-a5d0-528277751b99","nickname":“昵称”}]
 *      }
 * 返回：>=0 执行正确   ==0不要返加sendRoot无数据
 * *********************************/
int execJson(int fd,Json::Value root,Json::Value &sendRoot)
{

    int ret=0;
    string execName=root["exec"].asString();
    //printf("%d exec调用%s\n",fd,execName.c_str());
    //修改心情
    if(execName.compare("reMood")==0)
    {

        string param_1=root["param_1"].asString();
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
        setClientMood(fd,param_1);
            if(pExec!=NULL)
                pExec->reMood(handler->getNickname(),param_1);
            
        /*****************************************
        *	发通知 用户心情变化
        * 回:{"stype":"ret","exec":"reMood"
        *      ,"arrayRet":[{"fd":6,"uuid":"518e1f56-0857-49a7-a5d0-528277751b99","nickname":“昵称”,"mood":"心情"}]
        *      }
        ****************************************/
        Json::Value arrayUser;
        Json::Value item;
        item["fd"]=fd;
        item["nickname"]=handler->getNickname();
        item["uuid"]=handler->getUUID();
        item["mood"]=handler->getMood();
        arrayUser.append(item);
        sendRoot["stype"]="ret";
        sendRoot["exec"]="reMood";
        sendRoot["arrayRet"]=arrayUser;
        delete(handler);
        string sendStr=sendRoot.toStyledString();
        //printf("%s\n",sendStr.c_str());
        toNotInClients(fd,(char*)sendStr.c_str(),sendStr.size(),WDT_TXTDATA);
        }
        ret=0;//自发送
    }
    else if(execName.compare("regUser")==0)//注册帐户
    {
        string param_1=root["param_1"].asString();
        string param_2=root["param_2"].asString();
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                pExec->regName(param_1,param_2);
            delete(handler);
        }
        ret=0;
    }
    else if(execName.compare("rePassword")==0)//修改密码
    {
        string param_1=root["param_1"].asString();
        string param_2=root["param_2"].asString();
        string param_3=root["param_3"].asString();
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                pExec->rePassword(param_1,param_2,param_3);
            delete(handler);
        }
        ret=0;
    }
    else if(execName.compare("reOrgan")==0)
    {
        string param_1=root["param_1"].asString();
        string param_2=root["param_2"].asString();
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                pExec->reOrgan(param_1,param_2);
            delete(handler);
        }
        ret=0;
    }
    else if(execName.compare("reName")==0)
    {
        string param_1=root["param_1"].asString();
        string param_2=root["param_2"].asString();
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                pExec->reName(param_1,param_2);
            delete(handler);
        }
        ret=0;
    }
    else if(execName.compare("reMobileNumber")==0)
    {
        string param_1=root["param_1"].asString();
        string param_2=root["param_2"].asString();
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                pExec->reMobileNumber(param_1,param_2);
            delete(handler);
        }
        ret=0;
    }
    else if(execName.compare("readUserInfo")==0)
    {
        string param_1=root["param_1"].asString();        
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                {
                    Json::Value uinfo=pExec->getUserInfo(param_1);
                    if(uinfo.size()>0)
                     {

                        ret=uinfo.size();
                        sendRoot["stype"]="ret";
                        sendRoot["exec"]="readUserInfo";
                        sendRoot["arrayRet"]=uinfo;
                     }
                        else
                        {
                            ret=0;
                        }
                        
                }
            delete(handler);
        }
    }
    else if(execName.compare("readClients")==0)
    {
        //string param_1=root["param_1"].asString();        
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                {
                    Json::Value uinfo=pExec->getClient();
                    if(uinfo.size()>0)
                     {

                        ret=uinfo.size();
                        sendRoot["stype"]="ret";
                        sendRoot["exec"]="readClients";
                        sendRoot["arrayRet"]=uinfo;
                     }
                        else
                        {
                            ret=0;
                        }
                        
                }
            delete(handler);
        }
    }
    else if(execName.compare("readNoRegClients")==0)
    {
        //string param_1=root["param_1"].asString();        
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                {
                    Json::Value uinfo=pExec->getNoRegClient();
                    if(uinfo.size()>0)
                     {

                        ret=uinfo.size();
                        sendRoot["stype"]="ret";
                        sendRoot["exec"]="readNoRegClients";
                        sendRoot["arrayRet"]=uinfo;
                     }
                        else
                        {
                            ret=0;
                        }
                        
                }
            delete(handler);
        }
    }
    else if(execName.compare("readRegClients")==0)
    {
        //string param_1=root["param_1"].asString();        
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                {
                    Json::Value uinfo=pExec->getRegClient();
                    if(uinfo.size()>0)
                     {

                        ret=uinfo.size();
                        sendRoot["stype"]="ret";
                        sendRoot["exec"]="readRegClients";
                        sendRoot["arrayRet"]=uinfo;
                     }
                        else
                        {
                            ret=0;
                        }
                        
                }
            delete(handler);
        }
    }
    else if(execName.compare("readOrganUser")==0)
    {
        string param_1=root["param_1"].asString();        
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                {
                    Json::Value uinfo=pExec->getOrganClient(param_1);
                    if(uinfo.size()>0)
                     {

                        ret=uinfo.size();
                        sendRoot["stype"]="ret";
                        sendRoot["exec"]="readOrganUser";
                        sendRoot["arrayRet"]=uinfo;
                     }
                        else
                        {
                            ret=0;
                        }
                        
                }
            delete(handler);
        }
    }
    else if(execName.compare("readGroupUser")==0)
    {
        string param_1=root["param_1"].asString();        
        websocket_handler *handler=getClientValue(fd);
        if(handler!=NULL) {
            if(pExec!=NULL)
                {
                    Json::Value uinfo=pExec->getGroupClient(param_1);
                    if(uinfo.size()>0)
                     {

                        ret=uinfo.size();
                        sendRoot["stype"]="ret";
                        sendRoot["exec"]="readGroupUser";
                        sendRoot["arrayRet"]=uinfo;
                     }
                        else
                        {
                            ret=0;
                        }
                        
                }
            delete(handler);
        }
    }
    else {
        cout<<"未处理execJson: "<<execName<<endl;
    }
    return ret;
}
/******************************************
*登入
*   返回: >0成功 ,-1数据库中无用户 ,-2拒绝
*******************************************/
int join(int fd,string nickname,string pwd)
{
    int ret=0;
    Json::Value sendRoot;
    /***************************************
    * 来：{"stype":"join","message":"昵称"}
    * 回:{"stype":"Hi~"
    *      ,"fd":6,"uuid":"518e1f56-0857-49a7-a5d0-528277751b99","message":"欢迎你的到来......"
    *      }
    * *********************************/


    websocket_handler *handler=getClientValue(fd);
    if(handler!=NULL)
    {
        bool breg=false;
        string organ;
        string group;
        string mood;

        if(pExec!=NULL)
        {    
            ret=pExec->joinUser(nickname,pwd);
            if(ret==1){
            Json::Value userInfo;
            userInfo=pExec->getUserInfo(nickname);

            if(userInfo.size()>0)
            {
                Json::Value rows=userInfo["rows"];
                if(rows.size()>0)
                for(int i=0;i<rows.size();++i)
                {                    
                    organ=rows[i]["organ"].asString();
                    group=rows[i]["group"].asString();
                    mood=rows[i]["mood"].asString();
                }
            }
               breg=true; 
            }
            else if(ret==-2)
            {
            breg=false;
            delete(handler);
            deleteClient(fd);
            sendRoot["stype"]="ret";
            sendRoot["exec"]="join";
            sendRoot["return"]="非法登入";
            string sendStr=sendRoot.toStyledString();
            ret = webSocket_send(fd,(char*) sendStr.c_str(),sendStr.size(),false, WDT_TXTDATA);
            webSocket_send(fd,"quit",4,false,WDT_DISCONN);
            close(fd);
            return 0;
            }
            
        }




          setClientNickname(fd,nickname,breg);

          if(breg){//已注册用户      
          setClientGroup(fd,group);
          setClientOrgan(fd,organ);
          setClientMood(fd,mood);
          }

          sendRoot["stype"]="Hi~";
          sendRoot["fd"]=fd;
          sendRoot["uuid"]=handler->getUUID();
          sendRoot["organ"]=organ;
          sendRoot["group"]=group;
          sendRoot["mood"]=mood;
          sendRoot["breg"]=breg;
          sendRoot["message"]="欢迎你的到来......";
          string sendStr=sendRoot.toStyledString();
          ret = webSocket_send(fd,(char*) sendStr.c_str(),sendStr.size(),false, WDT_TXTDATA);
           //std::cout<<nickname<<" 加入，在线成员有"<<client_map.size()<<"个。"<<endl;
           /*****************************************
           *	发通知 用户上线
           * 回:{"stype":"newjoin"
           *      ,"arrayUser":[{"fd":6,"uuid":"518e1f56-0857-49a7-a5d0-528277751b99","nickname":“昵称”}]
           *      }
           ****************************************/
          Json::Value arrayUser;
          Json::Value item;
          item["fd"]=fd;
          item["nickname"]=nickname;
          item["uuid"]=handler->getUUID();
          item["mood"]=mood;
          item["organ"]=organ;
          item["group"]=group;
          item["breg"]=breg;
          arrayUser.append(item);
          sendRoot["stype"]="newjoin";
          sendRoot["arrayUser"]=arrayUser;
          sendStr=sendRoot.toStyledString();
          toNotInClients(fd,(char*)sendStr.c_str(),sendStr.size(),WDT_TXTDATA);
            
          delete(handler);
    }    

    return ret;
}
/***************************
 * 处理文本
 * ***************************/
int text_handle(int fd,char *buf)
{
    int ret;
                Json::Reader reader;
                    Json::Value root;
                    Json::Value sendRoot;
                    if(reader.parse(buf,root))//reader将字符串解析到root
                    {
                            string stype=root["stype"].asString();//访问节点
                            /***************************************
                             * 来：{"stype":"hi~"}
                             * 回:{"stype":"Hi~","message":"服务器回复，欢迎你的到来！","fd":6,"uuid":"518e1f56-0857-49a7-a5d0-528277751b99"}
                             * *********************************/
                            if(stype.compare("hi~") == 0)
                            {
                                websocket_handler* handler=getClientValue(fd);
                                if(handler!=NULL){
                                sendRoot["stype"]="Hi~";
                                sendRoot["message"]="服务器回复，欢迎你的到来！";
                                sendRoot["fd"]=fd;
                                sendRoot["uuid"]=handler->getUUID();
                                string sendStr=sendRoot.toStyledString();                                
                                ret = webSocket_send(fd,(char*) sendStr.c_str(),sendStr.size(),false, WDT_TXTDATA);
                                delete(handler);
                                }
                            }
                            else if(stype.compare(0,4,"exec")==0)
                           {
                                /***************************************
                                 * 来：{"stype":"exec","exec":"调用名","param_1":"参数1"........}
                                 * 回:{"stype":"ret"，"exec":"调用名","return":"返回值“
                                 *      ,"arrayRet":[{"fd":6,"uuid":"518e1f56-0857-49a7-a5d0-528277751b99","nickname":“昵称”}]
                                 *      }
                                 * *********************************/
                                websocket_handler *handler=getClientValue(fd);
                                if(handler)
                                {
                                    ret=execJson(fd,root,sendRoot);
                                    if(ret>0){
                                        string sendStr=sendRoot.toStyledString();
                                        ret=webSocket_send(fd,(char*)sendStr.c_str(),sendStr.size(),false,WDT_TXTDATA);
                                    }
                                    delete(handler);
                                }                               

                           }
                            else if(stype.compare(0,4,"join")==0)
                            {
                                     string nickname=root["nickname"].asString();
                                    string password=root["password"].asString();
                                    ret=join(fd,nickname,password);                               
                            }
                            
                            else if(stype.compare(0,5,"toall")==0)
                            {
                                /***************************************
                                 * 来：{"stype":"toall","message":"内容"}
                                 * 回:{"stype":"message","form":"来源昵称","fuuid":"来源uuid","ffd":6
                                 *     ,"message":"内容"
                                 *      }
                                 * *********************************/
                                websocket_handler *handler=getClientValue(fd);
                                if(handler!=NULL)
                                {
                                string fname=handler->getNickname();
                                string fuuid=handler->getUUID();
                                if(fname.size()>0){
                                    sendRoot["stype"]="message";
                                    sendRoot["form"]=fname;
                                  sendRoot["fuuid"]=fuuid;
                                    sendRoot["ffd"]=fd;
                                    sendRoot["message"]=root["message"];
                                    string sendStr=sendRoot.toStyledString();
                                    toNotInClients(fd,(char*)sendStr.c_str(),sendStr.size(),WDT_TXTDATA);
                                    
                                }
                                    delete(handler);
                                }

                            }
                            else if(stype.compare(0,4,"tofd")==0)
                            {
                                /***************************************
                                 * 来：{"stype":"tofd","tofd":7,"message":"内容"}
                                 * 回:{"stype":"message","form":"来源昵称","fuuid":"来源uuid","ffd":6
                                 *     ,"message":"内容"
                                 *      }
                                 * *********************************/
                                int tofd =root["tofd"].asInt();

                                if(isClient(tofd))
                                {
                                    websocket_handler *f_handler=getClientValue(fd);
                                    if(f_handler!=NULL)
                                    {
                                        string fname=f_handler->getNickname();
                                        string fuuid=f_handler->getUUID();
                                        sendRoot["stype"]="message";
                                        sendRoot["form"]=fname;
                                        sendRoot["ffd"]=fd;
                                        sendRoot["fuuid"]=fuuid;
                                        sendRoot["message"]=root["message"];
                                        string sendStr=sendRoot.toStyledString();
                                        ret = webSocket_send(tofd,(char*)sendStr.c_str(),sendStr.size(),false,WDT_TXTDATA);
                                        delete(f_handler);
                                    }
                                    
                                }
                            }
                            else if(stype.compare(0,2,"to")==0)
                            {
                                                            /***************************************
                                                             * 来：{"stype":"to","to":"昵称","message":"内容"}
                                                             * 回:{"stype":"message","form":"来源昵称","fuuid":"来源uuid","ffd":6
                                                             *     ,"message":"内容"
                                                             *      }
                                                             * *********************************/
                            string nickname=root["to"].asString();
                            int tofd=isNickname(nickname);
                            if(tofd>0)
                            {
                                websocket_handler *f_handler=getClientValue(fd);
                                    if(f_handler!=NULL)
                                    {
                                        string fname=f_handler->getNickname();
                                        string fuuid=f_handler->getUUID();
                                        sendRoot["stype"]="message";
                                        sendRoot["form"]=fname;
                                        sendRoot["ffd"]=fd;
                                        sendRoot["fuuid"]=fuuid;
                                        sendRoot["message"]=root["message"];
                                        string sendStr=sendRoot.toStyledString();
                                        ret = webSocket_send(tofd,(char*)sendStr.c_str(),sendStr.size(),false,WDT_TXTDATA);
                                        delete(f_handler);
                                    }
                            }

                            }
                    else if(stype.compare(0,7,"request")==0)//请求
                    {
                        /***************************************
                         * 来：{"stype":"request","tofd":7,"magic":38328,"request":"请接收文件？"}
                         * 转:{"stype":"request","tofd":7,"magic":38328,"request":"请接收文件？","form":"昵称","ffd":87,"fuuid":fuuid}
                         * *********************************/
                        
                                int tofd =root["tofd"].asInt();
                                if(isClient(tofd))
                                {
                                    websocket_handler *f_handler=getClientValue(fd);
                                    if(f_handler!=NULL)
                                    {
                                        string fname=f_handler->getNickname();
                                        string fuuid=f_handler->getUUID();
                                        sendRoot["stype"]="request";
                                        sendRoot["form"]=fname;
                                        sendRoot["ffd"]=fd;
                                        sendRoot["fuuid"]=fuuid;
                                        sendRoot["request"]=root["request"];
                                        sendRoot["tofd"]=tofd;
                                        sendRoot["magic"]=root["magic"].asInt();
                                        sendRoot["binType"]=root["binType"];

                                        sendRoot["label"]=root["label"].asString();
                                        sendRoot["maxPageLen"]=root["maxPageLen"].asInt();
                                        sendRoot["maxPageNum"]=root["maxPageNum"].asInt();
                                        string sendStr=sendRoot.toStyledString();
                                        ret = webSocket_send(tofd,(char*)sendStr.c_str(),sendStr.size(),false,WDT_TXTDATA);
                                        delete(f_handler);
                                    }
                                    
                                }                          


                    }
                    else if(stype.compare(0,8,"response")==0)//应答
                    {
                        /***************************************
                         * 来：{"stype":"response","tofd":7,"magic":38328,"response":"yes"}
                         * 转:{"stype":"response","tofd":7,"magic":38328,"response":"yes","form":"昵称","ffd":87,"fuuid":fuuid}
                         * *********************************/
                                int tofd =root["tofd"].asInt();
                                if(isClient(tofd))
                                {
                                    websocket_handler *f_handler=getClientValue(fd);
                                    if(f_handler!=NULL)
                                    {
                                        string fname=f_handler->getNickname();
                                        string fuuid=f_handler->getUUID();
                                        sendRoot["stype"]="response";
                                        sendRoot["form"]=fname;
                                        sendRoot["ffd"]=fd;
                                        sendRoot["fuuid"]=fuuid;
                                        sendRoot["response"]=root["response"];
                                        sendRoot["tofd"]=tofd;
                                        sendRoot["magic"]=root["magic"].asInt();
                                        
                                        string sendStr=sendRoot.toStyledString();
                                        ret = webSocket_send(tofd,(char*)sendStr.c_str(),sendStr.size(),false,WDT_TXTDATA);
                                        delete(f_handler);
                                    }
                                    
                                }                      


                    }
                            else if(stype.compare(0,11,"teamCommand")==0)//协助指令
                            {
                                /***************************************
                                 * 来：{"stype":"teamCommand","tofd":7,"magic":38328,"command":"指令"}
                                 * 转:{"stype":"teamCommand","tofd":7,"magic":38328,"command":"指令","form":"昵称","ffd":87,"fuuid":fuuid}
                                 * *********************************/
                                int tofd =root["tofd"].asInt();
                                if(isClient(tofd))
                                {
                                    websocket_handler *f_handler=getClientValue(fd);
                                    if(f_handler!=NULL)
                                    {
                                        string fname=f_handler->getNickname();
                                        string fuuid=f_handler->getUUID();
                                        sendRoot["stype"]="teamCommand";
                                        sendRoot["form"]=fname;
                                        sendRoot["ffd"]=fd;
                                        sendRoot["fuuid"]=fuuid;
                                        sendRoot["command"]=root["command"];
                                        sendRoot["tofd"]=tofd;
                                        sendRoot["magic"]=root["magic"].asInt();
                                        
                                        string sendStr=sendRoot.toStyledString();
                                        ret = webSocket_send(tofd,(char*)sendStr.c_str(),sendStr.size(),false,WDT_TXTDATA);
                                        delete(f_handler);
                                    }
                                    
                                }                             

                            }
                    else{
                        std::cerr<<std::endl<<"错误的JSON:"<<std::endl<<buf<<std::endl;
                    }
                }
                    return ret;
}

/******************************************
 * 响应客户端
 * 参数： fd 句柄
 *       datatype 数据类型
 *       buf 缓存
 *       bufLen 缓存大小
 * 说明：数据接收数据后，请在此对数据进行处理。
******************************************/
int server_callBack(int fd,WebsocketData_Type datatype, char *buf, unsigned int bufLen)
{
    int ret;
    WSCLIENT_IPC wsClient;
    if(bufLen > 0)
	{
        /*
		printf("server(fd/%d) recv:\r\n"
            "\t数据类型：%d\r\n"
            "\t数据长度byte:%d\r\n"
            "\t内容：%s\r\n"
            , fd,datatype,bufLen, buf);	
            */
		//===== 在这里根据客户端的请求内容, 提供相应的服务 =====
		
        addClient(fd);
        wsClient.fd=fd;
	    std::string strBuf=buf;
        if(datatype==WDT_DISCONN)//客户端主动下线通知
        {
            sprintf(wsClient.status,"DISCONN");
            /*****************************************
            *	发通知 用户下线
            * { "arrayUser" : [ { "fd" : 6, "nickname" : "昵称", "uuid" : "518e1f56-0857-49a7-a5d0-528277751b99" } ], "stype" : "dropline" }
            ****************************************/
            websocket_handler *handler=getClientValue(fd);
            if(handler!=NULL){
            
            Json::Value sendRoot;
            Json::Value arrayUser;
            Json::Value item;
            item["fd"]=fd;
            item["nickname"]=handler->getNickname();
            item["uuid"]=handler->getUUID();
            arrayUser.append(item);
            sendRoot["stype"]="dropline";
            sendRoot["arrayUser"]=arrayUser;
            string sendStr=sendRoot.toStyledString();
            toNotInClients(fd,(char*)sendStr.c_str(),sendStr.size(),WDT_TXTDATA);
            delete(handler);
            }
            //下线
            deleteClient(fd);
        }
        else if(datatype==WDT_TXTDATA){

            sprintf(wsClient.status,"TXTDATA");
           ret= text_handle(fd,buf);
            
        }
        else if(datatype==WDT_BINDATA)
        {

            //std::cout<<"未处理二进制数据: 来自fd:"<<fd<<endl;
            sprintf(wsClient.status,"BINDATA");
            wsimBIN_head *pHead=(wsimBIN_head*)buf;
            pHead->fromfd=fd;
            /*std::cout<<"index:"<<pHead->index;

            std::cout<<"\ttofd:"<<pHead->tofd;
            std::cout<<"\tformfd:"<<pHead->fromfd;
            //std::cout<<"\tlabel:"<<pHead->label;
            std::cout<<"\tmagic:"<<pHead->magic;
            std::cout<<"\tdatalen:"<<pHead->dataLen<<endl;
            if(pHead->bend==0)
                std::cout<<"转发结束包,"<<pHead->label<<endl;*/
            
            if(isClient(pHead->tofd)){
                ret=webSocket_send(pHead->tofd,buf,bufLen,false,WDT_BINDATA);
            }

        }
        else if(datatype==WDT_PING)
        {
            sprintf(wsClient.status,"PING");
            if(isClient(fd)){
                ret=webSocket_send(fd,"PONG",4,false,WDT_PONG);
            }

        }
        else
        {
            sprintf(wsClient.status,"未处理类型");
            std::cerr<<"未处理数据类型："<<datatype<<"；来自fd："<<fd<<";"<<bufLen<<"B"<<endl;
        }

            ;

           
	}
    struct msg_form msg;    
    //向共享内存写入数据
    if(wsshm!=NULL){       
            websocket_handler *handler=getClientValue(fd);
            if(handler!=NULL){
                
                sprintf(wsClient.nickname,handler->getNickname().c_str());
                wsClient.breg=handler->getReg();
                wsClient.bufLen=bufLen;
                sprintf(wsClient.organ,handler->getOrgan().c_str());
                sprintf(wsClient.group,handler->getGroup().c_str());
                delete(handler);
            }         
                    sem_p(wssemid);  /*访问资源*/                
                    memcpy(wsshm,&wsClient,WSCLIENTIPC_SIZE);
                    sem_v(wssemid);  /*释放资源*/                
                    msg.mtype = 9754;
                    msg.mtext = 'c';  /*发送消息通知读数据*/
                    msgsnd(wsmsqid, &msg, sizeof(msg.mtext), 0);                
            }
	return ret;
}
int server_callCloseed(int fd)
{
    //事件已发生，在此处理相关联的数据及联系事件
    //printf("server fd %d 关闭(事件),发生了错误。\r\n",fd);
    WSCLIENT_IPC wsClient;
    sprintf(wsClient.status,"CLOSEED");
    wsClient.fd=fd;
    websocket_handler *handler=getClientValue(fd);
    if(handler!=NULL){
                sprintf(wsClient.nickname,handler->getNickname().c_str());
                wsClient.breg=handler->getReg();
                wsClient.bufLen=0;
                sprintf(wsClient.organ,handler->getOrgan().c_str());
                sprintf(wsClient.group,handler->getGroup().c_str());
    Json::Value sendRoot;
    Json::Value arrayUser;
    Json::Value item;
    item["fd"]=fd;
    item["nickname"]=handler->getNickname();
        item["uuid"]=handler->getUUID();
    arrayUser.append(item);
    sendRoot["stype"]="dropline";
    sendRoot["arrayUser"]=arrayUser;
    string sendStr=sendRoot.toStyledString();
    toNotInClients(fd,(char*)sendStr.c_str(),sendStr.size(),WDT_TXTDATA);
    delete(handler);
    }
    //下线
    deleteClient(fd);
    struct msg_form msg;    
    //向共享内存写入数据
    if(wsshm!=NULL){
                
                    sem_p(wssemid);  /*访问资源*/                
                    memcpy(wsshm,&wsClient,WSCLIENTIPC_SIZE);
                    sem_v(wssemid);  /*释放资源*/                
                    msg.mtype = 9754;
                    msg.mtext = 'c';  /*发送消息通知读数据*/
                    msgsnd(wsmsqid, &msg, sizeof(msg.mtext), 0);                
            }
    return 0;
}


#define MAXFILE 65535
volatile sig_atomic_t _running = 1;
//signal handler
void sigterm_handler(int arg)
{
	_running = 0;
}

int main(void)
{
	pid_t pid;
    /* 屏蔽一些有关控制终端操作的信号
	 * 防止在守护进程没有正常运转起来时，因控制终端受到干扰退出或挂起
	 * */
	signal(SIGINT,  SIG_IGN);// 终端中断
	signal(SIGHUP,  SIG_IGN);// 连接挂断
	signal(SIGQUIT, SIG_IGN);// 终端退出
	signal(SIGPIPE, SIG_IGN);// 向无读进程的管道写数据
	signal(SIGTTOU, SIG_IGN);// 后台程序尝试写操作
	signal(SIGTTIN, SIG_IGN);// 后台程序尝试读操作
	signal(SIGTERM, SIG_IGN);// 终止
	// [1] fork child process and exit father process
	pid = fork();
	if(pid < 0)
	{
		perror("fork error!");
		exit(1);
	}
	else if(pid > 0)
	{
		exit(0);
	}
 
	// [2] create a new session
	setsid();
 
	// [3] set current path
	char szPath[1024];
	if(getcwd(szPath, sizeof(szPath)) == NULL)
	{
		perror("getcwd");
		exit(1);
	}
	else
	{
		chdir(szPath);
		printf("set current path succ [%s]\n", szPath);
	}
 
	// [4] umask 0
	umask(0);
 
	// [5] close useless fd
	int i;
	//for (i = 0; i < MAXFILE; ++i)
	for (i = 3; i < MAXFILE; ++i)
	{
		close(i);
	}
 
	// [6] set termianl signal
	signal(SIGTERM, sigterm_handler);
 
    printf("\nDaemon begin to work..., and use kill -9 %d to terminate\n",getpid());
    printf("\ninit DB...");
    printf("\nread %s ...",CFGFILE);
    imDB db;
    mycfg* pcfg=new mycfg(CFGFILE);
    
    std::string value;    
    value=pcfg->getValue( "DBSERVER");
    string strIP=DBSERVER;
    if(value.size()>0)
        strIP=value;
    value.resize(0);
    value=pcfg->getValue("DBUSER");
    string strUser=DBUSER;
    if(value.size()>0) strUser=value;
    value.resize(0);
    value=pcfg->getValue( "DBPASSWORD");
    string strPwd=DBPASSWORD;
    if(value.size()>0)
        strPwd=value;
    value.resize(0);
    value=pcfg->getValue("DBSPACE");
    string strSpace=DBSPACE;
    if(value.size()>0) strSpace=value;
    db.reInitDB(strIP,strUser,strPwd,strSpace);

    pExec=new execjson(db);
    //---------------------------------------共享内存------------------------
    key_t key;     
    struct shmid_ds buf1;  /*用于删除共享内存*/
    struct msqid_ds buf2;  /*用于删除消息队列*/ 

    

    // 获取key值
    if((key = ftok(".", 'x')) < 0)
    {
        perror("clients_IPC ftok error");
        goto WSSTART;
    }

    // 创建共享内存
    if((wsshmid = shmget(key, WSCLIENTIPC_SIZE, IPC_CREAT|0666)) == -1)
    {
        perror("clients_IPC Create Shared Memory Error");
        goto WSSTART;
    }

    // 连接共享内存
    wsshm = (char*)shmat(wsshmid, 0, 0);
    if((int)wsshm == -1)
    {
        perror("clients_IPC Attach Shared Memory Error");
        goto WSSTART;
    }

    // 创建消息队列
    if ((wsmsqid = msgget(key, IPC_CREAT|0777)) == -1)
    {
        perror("clients_IPC msgget error");
        goto WSSTART;
    }
    // 创建信号量
    wssemid = creat_sem(key);
    printf("\nIPC Shared Memory OK...\n");
WSSTART:
    pthread_mutex_init(&mutex_client_map_lock,NULL);
	int ret= server_init(SERVER_PROT,(CallBackFun*)&server_callBack,(CallCloseedFun*)&server_callCloseed);    
	while(_running)
	{
		usleep(1000*1000);//1 s
	}
    pthread_mutex_destroy(&mutex_client_map_lock);                      //销毁

    // 断开连接
    if(wsshm!=NULL){
            struct msg_form msg;
            msg.mtype = 9754;
            msg.mtext = 'q';
            msgsnd(wsmsqid, &msg, sizeof(msg.mtext), 0);
        shmdt(wsshm);
        /*删除共享内存、消息队列、信号量*/
        shmctl(wsshmid, IPC_RMID, &buf1);
        msgctl(wsmsqid, IPC_RMID, &buf2);
        del_sem(wssemid);
    }
    return ret;
//pthread_exit(ret);
}